/*
 *  MyDocument.mm
 *  NXTFace
 *
 *  Created by David Giovannini on 8/23/06.
 *  Copyright 2006 Software by Jove. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#import "NxtDevice.h"
#import "NxtOutput.h"
#import "NxtInput.h"

#include "SBJ/NXT/Device.h"

@implementation NxtDevice

// Construction

-(id) initWithDevice: (SBJ::NXT::Device*)theDevice;
{
    self = [super init];
    if (self != nil)
	{
		m_deviceRef = theDevice;
		m_outputA = [ [ NxtOutput alloc ] initOutputOf: self on: SBJ::NXT::out_A ];
		m_outputB = [ [ NxtOutput alloc ] initOutputOf: self on: SBJ::NXT::out_B ];
		m_outputC = [ [ NxtOutput alloc ] initOutputOf: self on: SBJ::NXT::out_C ];
		m_outputArray = [ NSArray arrayWithObjects: m_outputA, m_outputB, m_outputC, nil ];
		[ m_outputArray retain ];
		m_input1 = [ [ NxtInput alloc ] initInputOf: self on: SBJ::NXT::in_1 ];
		m_input2 = [ [ NxtInput alloc ] initInputOf: self on: SBJ::NXT::in_2 ];
		m_input3 = [ [ NxtInput alloc ] initInputOf: self on: SBJ::NXT::in_3 ];
		m_input4 = [ [ NxtInput alloc ] initInputOf: self on: SBJ::NXT::in_4 ];
		m_inputArray = [ NSArray arrayWithObjects: m_input1, m_input2, m_input3, m_input4, nil ];
		[ m_inputArray retain ];
    }
    return self;
}

-(void) dealloc
{
	[ m_outputA release ];
	[ m_outputB release ];
	[ m_outputC release ];
	[ m_input1 release ];
	[ m_input2 release ];
	[ m_input3 release ];
	[ m_input4 release ];
	[ super dealloc ];
}

// Accessors

-(SBJ::NXT::Device*) deviceRef
{
	return m_deviceRef;
}

-(NSArray*) Outputs
{
	return [ NSArray arrayWithArray: m_outputArray ];
}

-(NSArray*) Inputs
{
	return [ NSArray arrayWithArray: m_inputArray ];
}

-(NSString*) Name
{
	return [ NSString stringWithCString: m_deviceRef->getName().c_str() ];
}

-(void) setName: (NSString*)value
{
	m_deviceRef->setName( [ value cString ] );
}

-(NSString*) SessionName
{
	return [ NSString stringWithCString: m_deviceRef->getSessionName().c_str() ];
}

-(NSString*) ProgramName
{
	return [ NSString stringWithCString: m_deviceRef->getProgramName().c_str() ];
}

-(void) setProgramName: (NSString*)name
{
	m_deviceRef->runProgram( [ name UTF8String ] );
}

-(BOOL) IsConnected
{
	return *m_deviceRef;
}

-(BOOL) IsBluetooth
{
	return m_deviceRef->isBluetooth();
}

-(NSString*) Version
{
	return [ NSString stringWithCString: m_deviceRef->getVersion().toString().c_str() ];
}

-(double) BatteryLevel
{
	 return m_deviceRef->getBatteryLevel();
}

-(unsigned long) FreeSpace
{
	return m_deviceRef->getInfo().freeSpace;
}

// Commands

-(void) StartProgram: (NSString*)name
{
	m_deviceRef->runProgram( [ name UTF8String ] );
}

-(void) StopProgram
{
	m_deviceRef->stopProgram();
}

-(void) PlayToneAt: (unsigned short)hrz For:(double)secs
{
	m_deviceRef->playTone( hrz, secs );	
}

-(void) SendMessage: (NSString*)str To: (int)box;
{
	m_deviceRef->sendMessage( [ str UTF8String ], box );
}

-(NSString*) WaitForMessageFrom: (int)box Clear: (BOOL)clear
{
	return [ NSString stringWithCString: m_deviceRef->waitForMessage( box, clear ).c_str() ];
}

-(NSString*) GetLocalMessageFrom: (int)box Clear: (BOOL)clear
{
	return [ NSString stringWithCString: m_deviceRef->getLocalMessage( box, clear ).c_str() ];
}

-(NSString*) GetRemoteMessageFrom: (int)box Clear: (BOOL)clear
{
	return [ NSString stringWithCString: m_deviceRef->getRemoteMessage( box, clear ).c_str() ];
}

// Scriptability

-(NxtOutput*) objectInOutputsAtIndex: (int)index
{
	return [ m_outputArray objectAtIndex: index ];
}

-(NxtOutput*) valueInOutputsWithName: (NSString*)name
{
	int index = ::toupper( [ name cString ][ 0 ] ) - 'A';
	return [ m_outputArray objectAtIndex: index ];
}

-(NxtInput*) objectInInputsAtIndex: (int)index
{
	return [ m_inputArray objectAtIndex: index ];
}

-(NxtInput*) valueInInputsWithName: (NSString*)name
{
	int index = ::toupper( [ name cString ][ 0 ] ) - '1';
	return [ m_inputArray objectAtIndex: index ];
}

- (NSScriptObjectSpecifier *)objectSpecifier
{
	NSScriptClassDescription* containerClassDesc = (NSScriptClassDescription*)[ NSScriptClassDescription classDescriptionForClass: [ NSApp class ] ];
	return [ [ [ NSNameSpecifier alloc ] 
		initWithContainerClassDescription: containerClassDesc
		containerSpecifier: nil
		key: @"Devices"
		name: [ self SessionName ] ] autorelease ];
}

-(void) scripterSaysRunProgram:(NSScriptCommand*)command
{ 
    NxtDevice* directObj = [command evaluatedReceivers]; 
    NSString* p1 = [[command evaluatedArguments] valueForKey:@"program"]; 
    if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return; 
    } 
    [ self StartProgram: p1 ]; 
} 

-(void) scripterSaysTerminate:(NSScriptCommand*)command
{ 
    NxtDevice* directObj = [command evaluatedReceivers]; 
    if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return; 
    } 
    [ self StopProgram ]; 
} 

-(void) scripterSaysPlayTone:(NSScriptCommand*)command
{ 
    NxtDevice* directObj = [command evaluatedReceivers]; 
    NSNumber* p1 = [[command evaluatedArguments] valueForKey:@"at"]; 
    NSNumber* p2 = [[command evaluatedArguments] valueForKey:@"for"]; 
    if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return; 
    } 
    [ self PlayToneAt: [ p1 intValue ] For: [ p2 doubleValue ] ]; 
} 

-(void) scripterSaysWriteMessage:(NSScriptCommand*)command
{ 
    NxtDevice* directObj = [command evaluatedReceivers]; 
    NSString* p1 = [[command evaluatedArguments] valueForKey:@"message"]; 
    NSNumber* p2 = [[command evaluatedArguments] valueForKey:@"to"]; 
    if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return; 
    } 
    [ self SendMessage: p1 To: [ p2 intValue ] ]; 
} 

-(NSString*) scripterSaysWaitForMessage:(NSScriptCommand*)command
{
    NxtDevice* directObj = [command evaluatedReceivers]; 
    NSNumber* p1 = [[command evaluatedArguments] valueForKey:@"from"]; 
    if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return 0; 
    } 
    return [ self WaitForMessageFrom: [ p1 intValue ] Clear: TRUE ]; 
}

-(NSString*) scripterSaysReadLocalMessage:(NSScriptCommand*)command
{
    NxtDevice* directObj = [command evaluatedReceivers]; 
    NSNumber* p1 = [[command evaluatedArguments] valueForKey:@"from"]; 
    if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return 0; 
    } 
    return [ self GetLocalMessageFrom: [ p1 intValue ] Clear: TRUE ]; 
}

-(NSString*) scripterSaysReadRemoteMessage:(NSScriptCommand*)command
{
    NxtDevice* directObj = [command evaluatedReceivers]; 
    NSNumber* p1 = [[command evaluatedArguments] valueForKey:@"from"]; 
    if (self != directObj) { 
        //[self returnError:errOSACantAssign string:@"Invalid pairing."]; 
        return 0; 
    } 
    return [ self GetRemoteMessageFrom: [ p1 intValue ] Clear: FALSE ]; 
}

@end
